﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.Globalization;

using ECCIT;
using ECCIT.Extension.Weibo_v1.Common;
using ECCIT.Extension.Weibo_v1.Model;
using ECCIT.Extension.Weibo_v1.Lib;
using ECCIT.Extension.Weibo_v2.Common;
using ECCIT.Extension.Weibo_v2.Model;
using ECCIT.Extension.Weibo_v2.Lib;
using OgilvyOne.Sharan.Model;
using OgilvyOne.Sharan.IDAL;
using OgilvyOne.Sharan.DALFactory;

namespace OgilvyOne.Sharan.BLL
{
    using Microblog_v1 = ECCIT.Extension.Weibo_v1.Lib.Microblog;
    using Microblog_v2 = ECCIT.Extension.Weibo_v2.Lib.Microblog;
    using UserInfo_v1 = ECCIT.Extension.Weibo_v1.Model.UserInfo;
    using UserInfo_v2 = ECCIT.Extension.Weibo_v2.Model.UserInfo;
    using Users_v1 = ECCIT.Extension.Weibo_v1.Model.Users;
    using Users_v2 = ECCIT.Extension.Weibo_v2.Model.Users;
    using UserIDs_v2 = ECCIT.Extension.Weibo_v2.Model.UserIDs;
    using Statuses_v1 = ECCIT.Extension.Weibo_v1.Model.Statuses;
    using Statuses_v2 = ECCIT.Extension.Weibo_v2.Model.Statuses;
    using StatusInfo_v1 = ECCIT.Extension.Weibo_v1.Model.StatusInfo;
    using StatusInfo_v2 = ECCIT.Extension.Weibo_v2.Model.StatusInfo;
    using StatusType_v1 = ECCIT.Extension.Weibo_v1.Model.StatusType;
    using StatusType_v2 = ECCIT.Extension.Weibo_v2.Model.StatusType;
    using MicroblogException_v1 = ECCIT.Extension.Weibo_v1.Common.MicroblogException;
    using MicroblogException_v2 = ECCIT.Extension.Weibo_v2.Common.MicroblogException;
    using OAuthAccessToken_v1 = ECCIT.Extension.Weibo_v1.Common.OAuthAccessToken;
    using OAuthAccessToken_v2 = ECCIT.Extension.Weibo_v2.Common.OAuthAccessToken;

    public class WeiboUserBLL
    {
        public List<WeiboUserModel> GetAllWeiboUsers()
        {
            List<WeiboUserModel> users = null;
            try
            {
                users = WeiboUserDALFactory.Create().GetAllWeiboUsers();
            }
            catch (Exception ex)
            {
                users = null;
            }

            return users;
        }

        private void LoginToWeibo()
        {
            bool login = false;
            if (HttpContext.Current.Session["WeiboLoginTime"] != null)
            {
                DateTime loginTime = (DateTime)HttpContext.Current.Session["WeiboLoginTime"];
                if (DateTime.Now.Subtract(loginTime).Minutes < 60)
                    login = true;
            }

            if (!login)
            {
                Microblog_v1.Login(ConfigCacheManager.WeiboAccountName, ConfigCacheManager.WeiboAccountPassword);
                HttpContext.Current.Session["WeiboLoginTime"] = DateTime.Now;
            }
        }

        public string GetUserLatestStatusAboutSharan(string tag)
        {
            try
            {
                WeiboLogBLL logBll = new WeiboLogBLL();
                StringBuilder dataBuilder = new StringBuilder("<users>");

                List<WeiboUserModel> users = GetAllWeiboUsers();
                int logState = 1;
                string errorMsg = null;

                LoginToWeibo();

                foreach (WeiboUserModel user in users)
                {
                    // 判断距离上一次提交请求的时间
                    ResultInfo result = logBll.AllowRequestWeiboData(user.ID.Value);
                    if (!result.Result)
                    {
                        dataBuilder.Append(((WeiboLogModel)result.ReturnObject).RequestResult);
                        continue;
                    }

                    StringBuilder builder = null;
                    try
                    {
                        logState = 1;
                        //OAuthAccessToken_v1 token = Microblog_v1.Login(user.LoginName, user.Password);
                        //long userID = long.Parse(token.UserID);
                        UserInfo_v1 weiboUser = Microblog_v1.GetUserInfo(user.WeiboUserID.Value);
                        builder = new StringBuilder();

                        // get template id randomlly
                        Random r = new Random();
                        int templateID = r.Next() % ConfigCacheManager.TemplateCount;

                        builder.AppendFormat("<user id=\"{0}\" screen_name=\"{3}\" name=\"{1}\" profile_image_url=\"{2}\" age=\"{4}\" job=\"{5}\" hobby=\"{6}\" template=\"{7}\">", weiboUser.ID, weiboUser.Name, weiboUser.ProfileImageUrl, weiboUser.ScreenName, user.Age, user.Job, user.Hobby, templateID);
                        builder.AppendFormat("<statuses>");

                        bool ended = false;
                        long? maxID = long.MaxValue;
                        int foundCount = 0;
                        while (foundCount < ConfigCacheManager.WeiboPageSize && !ended)
                        {
                            Statuses_v1 statuses = Microblog_v1.GetUserStatuses(weiboUser.ID, null, maxID, null, 20, StatusType_v1.All, false);
                        
                            if (statuses.Items.Count < 20)
                                ended = true;
                            else
                                maxID = statuses.Items[statuses.Items.Count - 1].ID;

                            foreach (StatusInfo_v1 status in statuses.Items)
                            {
                                if (status.Text.Contains(tag))
                                {
                                    foundCount++;
                                    builder.AppendFormat("<status created_at=\"{0}\" bmiddle_pic=\"{1}\" original_pic=\"{2}\" thumbnail_pic=\"{3}\"><![CDATA[{4}]]></status>", FormatTime(status.CreatedAt), status.MiddlePic, status.OriginalPic, status.ThumbnailPic, status.Text);
                                    if (foundCount == 7)
                                        break;
                                }
                            }
                        }

                        builder.AppendFormat("</statuses>");
                        builder.Append("</user>");
                    }
                    catch (MicroblogException_v1 exLogin)
                    {
                        logState = 2;
                        errorMsg = exLogin.Message;
                        builder = new StringBuilder();
                        if (result.ReturnObject != null)
                            builder.Append(((WeiboLogModel)result.ReturnObject).RequestResult);
                    }

                    string data = builder.ToString();
                    dataBuilder.Append(data);
                    WeiboLogModel log = new WeiboLogModel(null, user.ID, null, DateTime.Now, logState, (logState==1) ? data : errorMsg);
                    logBll.Insert(log);
                }

                dataBuilder.Append("</users>");
                return dataBuilder.ToString();
            }
            catch (MicroblogException_v1 mex)
            {
                // 此处处理用户修改了登录密码导致抛出异常问题，具体方法待讨论
                throw mex;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private string FormatTime(string timeString)
        {
            // Sina weibo time format like: Thu Jan 26 09:29:28 +0800 2012
            string formatString = "ddd MMM dd " + CultureInfo.InvariantCulture.DateTimeFormat.LongTimePattern + " zzz yyyy";
            DateTimeOffset dto;
            if (DateTimeOffset.TryParseExact(timeString,
                                formatString,
                                CultureInfo.InvariantCulture,
                                DateTimeStyles.AllowLeadingWhite,
                                out dto))
                return dto.ToString("yyyy-MM-dd hh:mm:ss");
            else
                return timeString;
        }

        public string GetActiveFollowerStatuses(long userID)
        {
            try
            {
                // 判断距离上一次提交请求的时间
                WeiboLogBLL logBll = new WeiboLogBLL();
                ResultInfo result = logBll.AllowRequestWeiboData(userID);
                if (!result.Result && result.ReturnObject != null)
                    return ((WeiboLogModel)result.ReturnObject).RequestResult;

                // 首先获取登录用户互粉ID列表
                List<UserInfo_v2> foundUsers = new List<UserInfo_v2>();
                UserIDs_v2 userIDs = Microblog_v2.GetBilateralFriendUserIDs(userID, 2000, null, null);
                Users_v2 followers = Microblog_v2.GetActiveFollowers(userID, 200);
                foreach (UserInfo_v2 follower in followers.Items)
                {
                    if (!userIDs.IDs.Contains(follower.ID))    // 如果登录用户未关注该用户
                        continue;

                    foundUsers.Add(follower);

                    if (foundUsers.Count >= 6)
                        break;
                }

                foundUsers.Insert(0, Microblog_v2.GetUserInfo(userID)); //将当前登录用户数据加入list

                StringBuilder builder = new StringBuilder("<users>");
                foreach (UserInfo_v2 foundUser in foundUsers)
                {
                    StatusInfo_v2 status = foundUser.LatestStatus;
                    if (status == null)
                        continue;

                    builder.AppendFormat("<user id=\"{0}\" screen_name=\"{3}\" name=\"{1}\" profile_image_url=\"{2}\">", foundUser.ID, foundUser.Name, foundUser.ProfileImageUrl, foundUser.ScreenName);
                    builder.AppendFormat("<statuses>");
                    builder.AppendFormat("<status created_at=\"{0}\" bmiddle_pic=\"{1}\" original_pic=\"{2}\" thumbnail_pic=\"{3}\"><![CDATA[{4}]]></status>", FormatTime(status.CreatedAt), status.MiddlePic, status.OriginalPic, status.ThumbnailPic, status.Text);
                    builder.AppendFormat("</statuses>");
                    builder.Append("</user>");
                }
                builder.Append("</users>");

                string output = builder.ToString();

                WeiboLogModel log = new WeiboLogModel(null, null, userID, DateTime.Now, 1, output);
                logBll.Insert(log);

                return output;
            }
            catch (MicroblogException_v2 mex)
            {
                throw mex;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}